/*
 * Created on Dec 18, 2007
 */
package com.mgmaps.utils;

import java.io.*;
import java.util.*;
import javax.microedition.io.*;
import javax.microedition.io.file.*;
import com.mgmaps.tools.UITools;

/**
 * File handling utility methods, using JSR-75.
 *
 * @author CristiS
 * @version 1.0
 */
public class FileUtils extends IFileUtils {
  
  /**
   * Populate and show the list.
   */
  protected void populateList() throws Exception {
    if (currentDir == null) {
      // list roots
      Enumeration en = FileSystemRegistry.listRoots();

      // clear list
      UITools.deleteAll(fileList);
      
      // enumerate
      while(en.hasMoreElements()) {
        String root = (String) en.nextElement();
        if (!root.endsWith("/"))
          root += '/';
        fileList.append(root, null);
      }
    }
    
    else {
      // open directory
      FileConnection fconn = (FileConnection) Connector.open("file:///" + currentDir, Connector.READ);
      
      // clear list
      UITools.deleteAll(fileList);

      // list files
      fileList.append("../", null);
      for (Enumeration en = fconn.list(); en.hasMoreElements(); ) {
        String filename = (String) en.nextElement();
        
        // convert absolute to relative path
        int pos = filename.length()-2;
        while (pos >= 0 && filename.charAt(pos) != '/')
          pos--;
        if (pos >= 0)
          filename = filename.substring(pos+1);

        String checkFilename = filename;
        boolean isDir = filename.endsWith("/");
          
        // append only directories if type is FFTYPE_DIRCONTAINS, otherwise append all files
        if (fileFilterType != FFTYPE_DIRCONTAINS || isDir) {
          fileList.append(filename, null);
          if (isDir)
            checkFilename = filename.substring(0, filename.length()-1);
        }
          
        // check for matching file
        if (fileFilterType == FFTYPE_DIRCONTAINS && checkFilename.equals(fileFilter)) {
          // return current directory minus the ending '/'
          foundFile(currentDir.substring(0, currentDir.length()-1));
          return;
        }
      }
        
      // close directory
      fconn.close();
    }
  }

  /*
  public boolean dirExists(String filename) throws Exception {
    // open directory
    FileConnection fconn = (FileConnection) Connector.open("file:///" + filename, Connector.READ);
    // check if the file exists
    boolean ret = (fconn.exists() && fconn.isDirectory());
    // close the file connection
    fconn.close();
    return ret;
  }
  */
  
  /**
   * Open file input stream.
   * 
   * @param filename file name
   * @return input stream
   * @throws Exception if an exception occurs
   */
  public InputStream openFileInputStream(String filename) throws Exception {
    ExtLogger.debug("Loading " + filename);
    
    FileConnection fconn = (FileConnection) Connector.open(filename, Connector.READ);
    // commented to speed up
    // if (!fconn.exists() || !fconn.canRead())
    //   throw new Exception("File does not exist");

    return fconn.openInputStream();
  }
  
  /**
   * Read a file.
   * 
   * @param filename file path
   * @return data read
   * @throws IOException if an exception occurs
   */
  public byte[] readFile(String filename) throws Exception {
    ExtLogger.debug("Loading " + filename);
    
    FileConnection fconn = null;
    InputStream is = null;
    try {
      fconn = (FileConnection) Connector.open(filename, Connector.READ);
      // commented to speed up
      // if (!fconn.exists() || !fconn.canRead())
      //   throw new Exception("File does not exist");

      int sz = (int) fconn.fileSize();
      byte[] result = new byte[sz];
    
      is = fconn.openInputStream();
    
      /*
      // byte by byte
      for (int i = 0; i<sz; i++) {
        int c = is.read();
        result[i] = (byte) c;
      }
      */
    
      // multiple bytes
      int ch = 0;
      int rd = 0;
      while ((rd != sz) && (ch != -1)) {
        ch = is.read(result, rd, sz-rd);
        if (ch > 0)
          rd += ch;
      }
    
      return result;
    }
    finally {
      if (is != null)
        try {
          is.close();
        }
        catch (IOException ie) {
        }
      if (fconn != null)
        try {
          fconn.close();
        }
        catch (IOException ie) {
        }      
    }
  }
}
